<template>
  <el-card class="departmentTree">
    <template #header>
      <div class="card-header">
        <el-button
          class="button"
          type="text"
          @click="handleAdd"
        >
          新增
        </el-button>
      </div>
    </template>
    <el-tree
      ref="tree"
      node-key="id"
      :data="data"
      :props="defaultProps"
      :expand-on-click-node="false"
      :default-expanded-keys="defaultExpandedKeys"
      :highlight-current="true"
      @node-expand="nodeExpand"
      @node-collapse="nodeCollapse"
      @current-change="treeCurrentChange"
    >
      <template #default="{ node, data:nodeData }">
        <span class="treeNode">
          <p
            class="title"
            :title="node.label"
          >{{ node.label }}</p>
          <span class="edit">
            <el-dropdown @command="handleCommand">
              <el-icon
                color="#409EFF"
                size="18px"
              >
                <more-filled />
              </el-icon>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item :command="{type:'edit', nodeData}">修改</el-dropdown-item>
                  <el-dropdown-item :command="{type:'delete', nodeData}">删除</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </span>
        </span>
      </template>
    </el-tree>
    <DepartmentForm
      v-model:visible="visible"
      v-model:editId="editId"
      @success="handleSuccess"
    />
  </el-card>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue'
import { deleteDepartment, getDepartments } from '@/http/department'
import { ElMessageBox } from 'element-plus'
import type { IDepartment } from '@/http/types/department'
import type { IElTree } from '@/types/element-plus'
import DepartmentForm from './departmentForm.vue'

interface EmitsType {
  (e: 'currentChange', value: IDepartment): void
}
const emit = defineEmits<EmitsType>()
const visible = ref(false)
const data = ref<IDepartment[]>([])
const defaultProps = {
  value: 'id',
  label: 'displayName',
  children: 'children'
}
onMounted(() => {
  getData()
})
const tree = ref<IElTree>()
const defaultExpandedKeys = ref<string[]>([])
const getData = async () => {
  const { items } = await getDepartments()
  data.value = items
  const defaultKeys = data.value.map(e => e.id)
  defaultExpandedKeys.value = defaultExpandedKeys.value.concat(defaultKeys)
  // 默认展示第一节点的数据
  await nextTick()
  tree.value?.setCurrentKey(defaultKeys[0])
  const currentNode = tree.value?.getCurrentNode()
  if (!currentNode) return
  treeCurrentChange(currentNode as IDepartment)
}
const handleAdd = () => {
  visible.value = true
}
const handleSuccess = async () => {
  visible.value = false
  getData()
}
const nodeExpand = (data:any) => {
  defaultExpandedKeys.value.push(data.id)
}
const nodeCollapse = (data:any) => {
  defaultExpandedKeys.value.splice(defaultExpandedKeys.value.indexOf(data.id), 1)
}
const treeCurrentChange = (data:IDepartment) => {
  emit('currentChange', data)
}

const editId = ref('')
const handleCommand = (res:{
  type: 'edit'|'delete',
  nodeData: IDepartment
}) => {
  if (res.type === 'edit') {
    editId.value = res.nodeData.id
    visible.value = true
  }
  if (res.type === 'delete') {
    ElMessageBox.confirm(
      '删除该部门, 是否继续?',
      '提示',
      {
        confirmButtonText: '是',
        cancelButtonText: '否',
        type: 'warning'
      }
    )
      .then(async () => {
        await deleteDepartment(res.nodeData.id)
        getData()
      })
  }
}

</script>

<style lang="scss" scoped>
.departmentTree{
  width: 350px;
  .treeNode{
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
    overflow: hidden;
    &:hover{
      .edit{
        display: inline-block;
      }
    }
    .title{
      overflow: hidden;
      text-overflow:ellipsis;
      white-space: nowrap;
    }
    .edit{
      flex-shrink: 0;
      display: none;
      &:hover{
        opacity: .8;
      }
    }
  }
}
</style>
